home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / editdraw.i < prev    next >
Text File  |  1997-10-26  |  30KB  |  864 lines

  1. IMPLEMENTATION MODULE EditDraw;
  2.  
  3. FROM SYSTEM     IMPORT  ADDRESS, ADR, TSIZE, CADR, LOC, LONGWORD, WORD, CALLSYS;
  4.  
  5. (* Megamax-Lib *)
  6.  
  7. FROM GrafBase   IMPORT Rectangle, Point;
  8.  
  9. IMPORT Strings, FileNames, BinOps, Block, StrConv, MOSGlobals, Keyboard;
  10.  
  11. FROM Keyboard  IMPORT SpecialCode;
  12.  
  13. (* MagicLib *)
  14. IMPORT MagicAES, MagicVDI, MagicDOS, MagicSys, mtAlerts, mtAppl, mtDials, mtUtils;
  15.  
  16. FROM MagicVDI   IMPORT VDIIntIn, VDIPtsIn, VDIControl;
  17.  
  18. (* CAT Module *)
  19. FROM Void        IMPORT v;
  20. IMPORT CatGlobal;
  21.  
  22. (* Editor  *)
  23. FROM EditTypes  IMPORT EDITPTR, aLinePtr, aLineDesc, textPtr, aMark, deskSize, pixOff, CAT,
  24.                        CharSet, TrennSet, theDrawLine, maxBlocks;
  25.  
  26. FROM EditGlobals        IMPORT  SetDocument, Text, InqTextextend, isQuote,
  27.                                 ClipWork, MouseIsOn, HideMouse, ShowMouse, 
  28.                                 CursorIsOn, HideCursor, ShowCursor,
  29.                                 OutputLine;
  30.                                 
  31.  
  32. FROM EditTools          IMPORT  getCharPos, SetStartLine, SetCurrLine, SetInfoLine;
  33.  
  34. IMPORT EditBase;
  35.  
  36. IMPORT WdwManager, ConfVars, Varnames, RectFuncs;
  37.  
  38. VAR                                 
  39.     control7:       POINTER TO ADDRESS; (* it's tricky... *)
  40.     control9:       POINTER TO ADDRESS;
  41.  
  42.  
  43. PROCEDURE GetBlockRects (VAR ed: EDITPTR; VAR blockRects: ARRAY OF Rectangle;
  44.                          VAR count: INTEGER;
  45.                          oldLine : LONGINT; oldRow : INTEGER; 
  46.                          newLine : LONGINT; newRow : INTEGER);
  47.   VAR   i       : INTEGER;
  48.         viewLine: LONGINT;
  49.         cursOn  : BOOLEAN;
  50. BEGIN
  51.   WITH ed^ DO
  52.     (* OldLine muž kleiner sein, da es als Anfang genommen wird. *)
  53.     (* Erstmal Zeilen auf gltige Werte bringen *)
  54.     IF oldLine < 0 THEN oldLine := 0 END;
  55.     IF newLine < 0 THEN newLine := 0 END;
  56.     IF newLine > totalLineNr (* - 1 *) THEN newLine := totalLineNr (* - 1 *) END;
  57.     IF oldLine > totalLineNr (* - 1 *) THEN oldLine := totalLineNr (* - 1 *) END;
  58.     (* Notfalls swappen! *)
  59.     IF oldLine > newLine THEN 
  60.       v.lint := newLine; newLine := oldLine; oldLine := v.lint; 
  61.       v.int := newRow; newRow := oldRow; oldRow := v.int;
  62.     ELSIF (oldLine = newLine) & (oldRow > newRow) 
  63.     THEN 
  64.       v.int := newRow; newRow := oldRow; oldRow := v.int;
  65.     END;
  66.     i := 0;
  67.     (* Jetzt gewnschten Bereich malen *)
  68.     IF (oldLine >= 0) & (newLine >= 0) & (newLine >= oldLine)
  69.     THEN
  70.       (* Block ist vorhanden *)
  71.       IF ~(((oldLine < StartLine) & (newLine < StartLine)) OR (oldLine > StartLine + LONG(windLines)))
  72.       THEN 
  73.         (* Block ist zumindest teilweise im Fenster. 
  74.          * Es werden maximal drei Rechtecke berechnet, die den Block im Fenster komplett beschreiben. 
  75.          *)
  76.         IF (oldLine >= StartLine)
  77.         THEN 
  78.           WITH blockRects[i] DO 
  79.             getCharPos (ed, oldLine, oldRow, x, y);
  80.             IF x <= editWork.x + pixOff THEN x := editWork.x + pixOff END;
  81.             IF newLine = oldLine
  82.             THEN 
  83.               getCharPos (ed, newLine, newRow, w, h);
  84.               DEC (w);
  85.               INC (h, charHeight-1);
  86.             ELSE
  87.               w := editWork.x + editWork.w - 1;
  88.               h := y + charHeight-1;
  89.             END;
  90.             INC (i);
  91.           END (* WITH blockRects [i] *);
  92.         END;
  93.         (* Komplette Zeilen zwischen Start und Ende *)
  94.         IF (newLine > oldLine + 1) 
  95.         THEN 
  96.           (* mindestens eine Zeile im Fenster *)
  97.           viewLine := BinOps.HigherLInt (oldLine + 1, StartLine);
  98.           WITH blockRects[i] DO 
  99.             getCharPos (ed, viewLine, 0, x, y);
  100.             viewLine := BinOps.LowerLInt (newLine - 1, StartLine + LONG(windLines));
  101.             getCharPos (ed, viewLine, 0, v.int, h);
  102.             INC (h, charHeight-1);
  103.             x := editWork.x+pixOff;
  104.             w := editWork.x + editWork.w - 1;
  105.           END;
  106.           INC(i);
  107.         END;
  108.         IF (newLine >= StartLine) & (newLine <= StartLine + LONG(windLines)) & (newLine # oldLine)
  109.         THEN
  110.           (* Blockende im Fenster und nicht in Startzeile *)
  111.           WITH blockRects[i] DO 
  112.             x := editWork.x+pixOff;
  113.             getCharPos (ed, newLine, newRow, w, y);
  114.             DEC (w);
  115.             h := y + charHeight - 1;
  116.           END;
  117.           INC(i);
  118.         END;
  119.       END;
  120.     END;
  121.   END;
  122.   count := i;
  123. END GetBlockRects;
  124.  
  125. PROCEDURE MarkArea (VAR ed : EDITPTR; oldLine : LONGINT; oldRow : INTEGER; 
  126.                     newLine : LONGINT; newRow : INTEGER; clipIt : BOOLEAN);
  127.   VAR   work, c, 
  128.         clip    : Rectangle;
  129.         i, j    : INTEGER;
  130.         viewLine: LONGINT;
  131.         blockRects : ARRAY [0..2] OF Rectangle;
  132.         cursOn  : BOOLEAN;
  133. BEGIN
  134.   HideMouse();
  135.   IF clipIt THEN HideCursor (ed); END;
  136.   WITH ed^ DO 
  137.     IF clipIt
  138.     THEN 
  139.       (* selber clippen *)
  140.       ClipWork (ed);
  141.     END; 
  142.     GetBlockRects (ed, blockRects, i, oldLine, oldRow, newLine, newRow);
  143.     (*
  144.  
  145.     (* OldLine muž kleiner sein, da es als Anfang genommen wird. *)
  146.     (* Erstmal Zeilen auf gltige Werte bringen *)
  147.     IF oldLine < 0 THEN oldLine := 0 END;
  148.     IF newLine < 0 THEN newLine := 0 END;
  149.     IF newLine > totalLineNr (* - 1 *) THEN newLine := totalLineNr (* - 1 *) END;
  150.     IF oldLine > totalLineNr (* - 1 *) THEN oldLine := totalLineNr (* - 1 *) END;
  151.     (* Notfalls swappen! *)
  152.     IF oldLine > newLine THEN 
  153.       v.lint := newLine; newLine := oldLine; oldLine := v.lint; 
  154.       v.int := newRow; newRow := oldRow; oldRow := v.int;
  155.     ELSIF (oldLine = newLine) & (oldRow > newRow) 
  156.     THEN 
  157.       v.int := newRow; newRow := oldRow; oldRow := v.int;
  158.     END;
  159.     (* Jetzt gewnschten Bereich malen *)
  160.     IF (oldLine >= 0) & (newLine >= 0) & (newLine >= oldLine)
  161.     THEN
  162.       (* Block ist vorhanden *)
  163.       IF ~(((oldLine < StartLine) & (newLine < StartLine)) OR (oldLine > StartLine + LONG(windLines)))
  164.       THEN 
  165.         (* Block ist zumindest teilweise im Fenster. 
  166.          * Es werden maximal drei Rechtecke berechnet, die den Block im Fenster komplett beschreiben. 
  167.          *)
  168.         i := 0;
  169.         IF (oldLine >= StartLine)
  170.         THEN 
  171.           WITH blockRects[i] DO 
  172.             getCharPos (ed, oldLine, oldRow, x, y);
  173.             IF x <= editWork.x + pixOff THEN x := editWork.x + pixOff END;
  174.             IF newLine = oldLine
  175.             THEN 
  176.               getCharPos (ed, newLine, newRow, w, h);
  177.               DEC (w);
  178.               INC (h, charHeight-1);
  179.             ELSE
  180.               w := editWork.x + editWork.w - 1;
  181.               h := y + charHeight-1;
  182.             END;
  183.             INC (i);
  184.           END (* WITH blockRects [i] *);
  185.         END;
  186.         (* Komplette Zeilen zwischen Start und Ende *)
  187.         IF (newLine > oldLine + 1) 
  188.         THEN 
  189.           (* mindestens eine Zeile im Fenster *)
  190.           viewLine := BinOps.HigherLInt (oldLine + 1, StartLine);
  191.           WITH blockRects[i] DO 
  192.             getCharPos (ed, viewLine, 0, x, y);
  193.             viewLine := BinOps.LowerLInt (newLine - 1, StartLine + LONG(windLines));
  194.             getCharPos (ed, viewLine, 0, v.int, h);
  195.             INC (h, charHeight-1);
  196.             x := editWork.x+pixOff;
  197.             w := editWork.x + editWork.w - 1;
  198.           END;
  199.           INC(i);
  200.         END;
  201.         IF (newLine >= StartLine) & (newLine <= StartLine + LONG(windLines)) & (newLine # oldLine)
  202.         THEN
  203.           (* Blockende im Fenster und nicht in Startzeile *)
  204.           WITH blockRects[i] DO 
  205.             x := editWork.x+pixOff;
  206.             getCharPos (ed, newLine, newRow, w, y);
  207.             DEC (w);
  208.             h := y + charHeight - 1;
  209.           END;
  210.           INC(i);
  211.         END;
  212.         (* alle rechtecke berechnet *)
  213. *)
  214.     IF i > 0
  215.     THEN
  216.       v.int := MagicVDI.SetWritemode (hdl, MagicVDI.XOR);
  217.       v.int := MagicVDI.SetFillcolor (hdl, MagicAES.BLACK);
  218.       (* Jetzt Rechteckliste abfragen und auf Rechtecke clippen *)
  219.       IF clipIt 
  220.       THEN
  221.         IF WdwManager.RectList (wdw, 0, work)
  222.         THEN
  223.           REPEAT
  224.             (* kleinsten Redrawbereich bestimmen *)
  225.             c := RectFuncs.ClipRect (work, deskSize);
  226.             c := RectFuncs.ClipRect (c, editWork);
  227.             IF c.w > 0 THEN
  228.               INC (c.w, c.x-1);
  229.               INC (c.h, c.y-1);
  230.               MagicVDI.SetClipping (hdl, c, TRUE);
  231.               FOR j := 0 TO i-1 DO 
  232.                 IF (blockRects[j].w > blockRects[j].x) & (blockRects[j].h > blockRects[j].y) THEN
  233.                   MagicVDI.FillRectangle (hdl, blockRects[j]);
  234.                 END;
  235.               END;
  236.               ClipWork (ed);
  237.             END;
  238.           UNTIL ~WdwManager.RectList (wdw, 1, work);
  239.         END;
  240.       ELSE
  241.         FOR j := 0 TO i-1 DO 
  242.           IF (blockRects[j].w > blockRects[j].x) & (blockRects[j].h > blockRects[j].y) THEN
  243.             MagicVDI.FillRectangle (hdl, blockRects[j]);
  244.           END;
  245.         END;
  246.       END;
  247.       v.int := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  248.       v.int := MagicVDI.SetFillcolor (hdl, backCol);
  249.     END; 
  250.   END (* WITH ed^ *);
  251.   IF clipIt THEN ShowCursor (ed); END;
  252.   ShowMouse (FALSE);
  253. END MarkArea; 
  254.  
  255.         (* Vorhandener Block wird angezeigt *)
  256. PROCEDURE ShowBlockMark (VAR ed : EDITPTR; clipIt : BOOLEAN);
  257.   VAR   clip    : Rectangle;
  258.         i, j    : INTEGER;
  259.         viewLine: LONGINT;
  260.         blockRects : ARRAY [0..2] OF Rectangle;
  261.         cursOn  : BOOLEAN;
  262. BEGIN
  263.   WITH ed^ DO 
  264.     FOR i := 0 TO maxBlocks - 1 DO
  265.       WITH blocks[i] DO
  266.         IF (blockStart.line >= 0) & (blockEnd.line >= 0)(* & (blockEnd.line >= blockStart.line) *)
  267.         THEN
  268.           MarkArea (ed, blockStart.line, blockStart.row, blockEnd.line, blockEnd.row, clipIt);
  269.         END;
  270.       END;
  271.     END;
  272.   END;
  273. END ShowBlockMark;
  274.  
  275. PROCEDURE ConvertCR (VAR s : ARRAY OF CHAR; VAR l : INTEGER);
  276. BEGIN
  277.   IF (l>0) & (s[l-1] = 15C) THEN DEC (l); s[l] := 0C END;
  278. END ConvertCR;
  279.  
  280. PROCEDURE MakeDrawLine (ed : EDITPTR; lineNr : LONGINT; VAR drawLine : ARRAY OF CHAR; VAR l : INTEGER);
  281.   VAR tmpLine : ARRAY [0..4095] OF CHAR;
  282.       gotLine : BOOLEAN;
  283. BEGIN
  284.   WITH ed^ DO
  285.     gotLine := EditBase.GetLine (ed, lineNr, drawLine, l);
  286.     IF (gotLine OR (l > INTEGER(HIGH (drawLine))))
  287.     THEN
  288.       IF (l>0) & (drawLine[l-1] = 12C) THEN DEC (l); drawLine[l] := 0C; END;
  289.       IF ~umbruch OR ~showCR
  290.       THEN
  291.         ConvertCR (drawLine, l);
  292.       END;
  293.       IF (l>0) & (drawLine[l-1] = 12C) THEN DEC (l); drawLine[l] := 0C; END;
  294.       IF realTabs
  295.       THEN
  296.         Strings.Assign (drawLine, tmpLine, v.bool);
  297.         CatGlobal.ConvertTabs (tmpLine, drawLine, tabSize);
  298.         l := LENGTH (drawLine);
  299.       END;
  300.     ELSE
  301.       drawLine[0] := "";
  302.       l := 0;
  303.     END;
  304.   END;
  305. END MakeDrawLine;
  306.  
  307. (*
  308. PROCEDURE OutputLine (ed : EDITPTR; x, y : INTEGER; REF line : ARRAY OF CHAR);
  309. BEGIN
  310.   WITH ed^ DO
  311.     IF readOnly & isQuote (line)
  312.     THEN
  313.       IF mtAppl.Bitplanes > 1
  314.       THEN
  315.         (* Farbe umsetzen auf Quotefarbe *)
  316.         v.int := MagicVDI.SetTextcolor (hdl, quoteCol);
  317.         (* Zeile ausgeben *)
  318.         Text (ed, x, y, line);
  319.         (* Farbe wieder zurcksetzen *)
  320.         v.int := MagicVDI.SetTextcolor (hdl, textCol);
  321.       ELSE
  322.         (* Texteffekt umsetzen *)
  323.         v.bset := MagicVDI.SetTexteffect (hdl, quoteEff);
  324.         (* Zeile ausgeben *)
  325.         Text (ed, x, y, line);
  326.         v.bset := MagicVDI.SetTexteffect (hdl, {});
  327.       END;
  328.     ELSE
  329.       Text (ed, x, y, line);
  330.     END;
  331.   END;
  332. END OutputLine;
  333. *)
  334. PROCEDURE rawRedraw (ed : EDITPTR; clip : Rectangle);
  335.   (* Geht davon aus, daž RectFuncs.ClipRect gesetzt ist und nur Zeilen zu zeichnen sind! 
  336.    *)
  337. VAR cursOn : BOOLEAN;
  338.     text   : textPtr;
  339.     extend : ARRAY [0..3] OF Point;
  340.     i      : INTEGER;
  341.     width  : INTEGER;
  342.     xOutput, 
  343.     yOutput: INTEGER;
  344.     l      : INTEGER;
  345.     topLine: LONGINT;
  346. BEGIN
  347.   WITH ed^ DO
  348.     v.int := MagicVDI.SetTextcolor (hdl, textCol);
  349.     v.int := MagicVDI.SetWritemode (hdl, MagicVDI.TRANSPARENT);
  350.     topLine := StartLine;
  351.     i := 0;   (* Zeilenz„hler im Fenster *)
  352.     (* Nicht im Redrawbereich liegende Zeilen berspringen *)
  353.     WHILE (topLine < totalLineNr) & ((editWork.y + (i+1)*charHeight) - 1 < clip.y) DO
  354.       INC (topLine);
  355.       INC(i);
  356.     END;
  357.     xOutput := editWork.x + pixOff - leftOffset;
  358.     yOutput := editWork.y + i * charHeight;
  359.     (* Jetzt zeichnen *)
  360.     WHILE (topLine < totalLineNr) & (i < editWork.h DIV charHeight) 
  361.           & (yOutput <= clip.h) DO
  362.       MakeDrawLine (ed, topLine, theDrawLine, l);
  363.       text := ADR (theDrawLine);
  364.       (*
  365.       IF monoSpaced & ~realTabs
  366.       THEN
  367.         width := l * charWidth;
  368.       ELSE
  369.         InqTextextend (ed, text^, extend, TRUE);
  370.         width := extend[1].x - extend[0].x;
  371.       END;
  372.       *)
  373.       OutputLine (ed, xOutput, yOutput, text^, l, width);
  374.       IF width < 32767
  375.       THEN
  376.         maxWidth := BinOps.HigherInt (maxWidth, width + charWidth);
  377.       END;
  378.       INC(i);
  379.       INC (topLine);
  380.       INC (yOutput, charHeight);
  381.     END;
  382.     v.int := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  383.     ShowBlockMark (ed, FALSE);
  384.   END (* WITH ed *);
  385. END rawRedraw;
  386.  
  387.         (* Alle redraw-Funktionen *)
  388. PROCEDURE redrawWdw (wdw, vdiH : INTEGER; special : ADDRESS; frame : Rectangle);
  389. VAR clip : Rectangle;
  390.     i    : INTEGER;
  391.     cursOn : BOOLEAN;
  392.     strAdr : textPtr;
  393.     ed     : EDITPTR;
  394.     oldMax : INTEGER;
  395.     wr     : INTEGER;
  396.     eff    : INTEGER;
  397.     currSize : Rectangle;
  398.     wasRO  : BOOLEAN;
  399. BEGIN
  400.   ed := EDITPTR (special);
  401.   WITH ed^ DO
  402.     IF readOnly
  403.     THEN
  404.       textCol := CatGlobal.viewTextCol;
  405.       backCol := CatGlobal.viewBackCol;
  406.       quoteCol := CatGlobal.viewQuoteCol;
  407.       CASE CatGlobal.viewQuoteEff OF
  408.         0 : quoteEff := {}; |
  409.         1 : quoteEff := {MagicVDI.Fat}; |
  410.         2 : quoteEff := {MagicVDI.Italic}; |
  411.         3 : quoteEff := {MagicVDI.Light}; |
  412.       ELSE
  413.         quoteEff := {};
  414.       END;
  415.     ELSE
  416.       textCol := CatGlobal.editTextCol;
  417.       backCol := CatGlobal.editBackCol;
  418.       quoteCol := textCol;
  419.     END;
  420.     (* Jetzt ggf. Farben bei monochrom ignorieren und nur von Hintergrundfarbe
  421.      * ausgehen 
  422.      *)
  423.     IF (mtAppl.Bitplanes = 1)
  424.     THEN
  425.       IF (textCol > 0) OR (quoteCol > 0)
  426.       THEN
  427.         backCol := 0;
  428.         IF textCol = 0 THEN textCol := 1 END;
  429.         IF quoteCol = 0 THEN quoteCol := 1 END;
  430.       ELSE
  431.         IF backCol = 0 THEN backCol := 1 END;
  432.       END
  433.     END;
  434.     (* Clipping auf Rectangle setzen *)
  435.     IF hasUserProc
  436.     THEN
  437.       clip := frame;
  438.       IF RectFuncs.rcIntersect (userRect, clip)
  439.       THEN
  440.         WdwManager.GetWdwWork (wdw, currSize);
  441.         clip := currSize;
  442.         ed^.drawUserArea (wdw, hdl, clip, frame, textCol, backCol);
  443.       END;
  444.     END;
  445.     clip := frame;
  446.     IF RectFuncs.rcIntersect ( editWork, clip)
  447.     THEN
  448.       oldMax := maxWidth;
  449.       clip := RectFuncs.ClipRect (frame, editWork);
  450.       clip.w := clip.x + clip.w - 1; 
  451.       clip.h := clip.y + clip.h -1;
  452.       
  453.       v.int := MagicVDI.SetFillcolor (hdl, backCol);
  454.       
  455.       MagicVDI.FillRectangle(hdl, clip);
  456.       
  457.  
  458.       IF clip.x = editWork.x THEN
  459.         INC (clip.x, pixOff);
  460.       END;
  461.       
  462.       clip.x := BinOps.LowerInt (clip.x, clip.w);
  463.       
  464.       WdwManager.SetClip (hdl, clip, FALSE);
  465.  
  466.       rawRedraw (ed, clip);
  467.       
  468.       IF oldMax # maxWidth THEN SetDocument (ed) END;
  469.     END;
  470.     ClipWork (ed);
  471.   END (* WITH ed^ DO *);
  472. END redrawWdw;
  473.  
  474. PROCEDURE redrawLines (ed : EDITPTR; fromLine : INTEGER);
  475.   VAR frame : Rectangle;
  476. BEGIN
  477.   WITH ed^ DO 
  478.     HideCursor (ed);
  479.     frame := editWork;
  480.     frame.y := editWork.y + fromLine * charHeight;
  481.     WdwManager.RedrawWdw (ed^.wdw, frame);
  482.     ShowCursor (ed);
  483.   END;
  484. END redrawLines;
  485.  
  486. PROCEDURE redrawLineArea (ed : EDITPTR; fromLine, toLine : LONGINT);
  487. (* Hier werden richtige Zeilennummern bergeben, nicht die Bildschirmzeilen *)
  488.   VAR frame : Rectangle;
  489. BEGIN
  490.   WITH ed^ DO 
  491.     IF ((fromLine >= StartLine) & (fromLine < StartLine + LONG(windLines))) OR
  492.        ((toLine >= StartLine) & (toLine < StartLine + LONG(windLines)))
  493.     THEN
  494.       (* Nur Bereich neu zeichnen *)
  495.       HideCursor (ed);
  496.       frame := editWork;
  497.       IF fromLine > StartLine
  498.       THEN
  499.         frame.y := editWork.y + SHORT(fromLine-StartLine) * charHeight;
  500.       END;
  501.       IF toLine < StartLine + LONG (windLines)
  502.       THEN
  503.         frame.h := editWork.y + SHORT(toLine-StartLine+1) * charHeight;
  504.         frame.h := frame.h - frame.y + 1;
  505.       END;
  506.       WdwManager.RedrawWdw (ed^.wdw, frame);
  507.       ShowCursor (ed);
  508.     ELSIF (fromLine < StartLine) & (toLine > StartLine)
  509.     THEN
  510.       (* komplett neu zeichnen *)
  511.       HideCursor (ed);
  512.       WdwManager.RedrawWdw (ed^.wdw, editWork);
  513.       ShowCursor (ed);
  514.     END;
  515.   END;
  516. END redrawLineArea;
  517.  
  518.         (* Scroll-Funktionen *)
  519.  
  520.  
  521. PROCEDURE scrollRegion (ed : EDITPTR; from, to, amount : INTEGER);
  522. VAR pscrMFDB,
  523.     pdesMFDB : MagicVDI.MFDB;
  524.     copy     : ARRAY [0..1] OF Rectangle;
  525.     clip     : Rectangle;
  526.     flag     : INTEGER;
  527.     dir      : INTEGER;
  528. BEGIN
  529.   WITH ed^ DO 
  530.     IF from = to THEN RETURN END;
  531.     copy[0].x := BinOps.LowerInt(mtAppl.MaxWidth-1, editWork.x);
  532.     copy[0].w := BinOps.LowerInt(mtAppl.MaxWidth-1, editWork.w);
  533.     copy[0].y := BinOps.LowerInt(mtAppl.MaxHeight-1, editWork.y+from*charHeight);
  534.     IF from < to 
  535.     THEN
  536.       copy[0].h := BinOps.LowerInt(mtAppl.MaxHeight-1, (to - from + 1) * charHeight);
  537.     ELSE
  538.       copy[0].h := BinOps.LowerInt(mtAppl.MaxHeight-1, (to - from + 1) * charHeight);
  539.     END;
  540.     IF amount > 0
  541.     THEN 
  542.       dir := WdwManager.UP;
  543.     ELSE
  544.       dir := WdwManager.DOWN;
  545.       amount := -1 * amount;
  546.     END;
  547.     amount := amount * charHeight;
  548.     WdwManager.ScrollInWdw (wdw, copy[0], dir, amount);
  549.   (*
  550.     (* X-Koordinaten festlegen *)
  551.     copy[0].x := BinOps.LowerInt(mtAppl.MaxWidth-1, editWork.x);
  552.     copy[0].w := BinOps.LowerInt(mtAppl.MaxWidth-1, editWork.x+editWork.w-1);
  553.     copy[1].x := BinOps.LowerInt(mtAppl.MaxWidth-1, editWork.x);
  554.     copy[1].w := BinOps.LowerInt(mtAppl.MaxWidth-1, editWork.x+editWork.w-1);
  555.     (* y-Koordinaten berechnen *)
  556.     copy[0].y := BinOps.LowerInt(mtAppl.MaxHeight-1, editWork.y+from*charHeight);
  557.     copy[0].h := BinOps.LowerInt(mtAppl.MaxHeight-1, editWork.y+to*charHeight-1);
  558.     copy[1].y := BinOps.LowerInt(mtAppl.MaxHeight-1, editWork.y+from*charHeight+amount*charHeight);
  559.     copy[1].h := BinOps.LowerInt(mtAppl.MaxHeight-1, editWork.y+to*charHeight+amount*charHeight-1);
  560.     pscrMFDB.fdAddr := NIL;  pdesMFDB.fdAddr := NIL;
  561.     flag := 0;
  562.     WHILE WdwManager.RectList (wdw, flag, clip) DO
  563.       WdwManager.SetClip (hdl, clip, TRUE);
  564.       MagicVDI.CopyRasterOpaque(hdl, 3, copy, pscrMFDB, pdesMFDB);
  565.       flag := 1;
  566.     END;
  567.     ClipWork (ed);
  568.     *)
  569.   END;
  570. END scrollRegion;
  571.  
  572.  
  573. PROCEDURE IsInBlock (VAR ed : EDITPTR; lnr : LONGINT) : BOOLEAN;
  574.   VAR i : INTEGER;
  575. BEGIN
  576.   FOR i := 0 TO maxBlocks-1 DO
  577.     WITH ed^.blocks[i] DO
  578.       IF (blockStart.line <= lnr) & (blockEnd.line >= lnr)
  579.       THEN
  580.         RETURN TRUE
  581.       END;
  582.     END;
  583.   END;
  584.   RETURN FALSE;
  585. END IsInBlock;
  586.  
  587. PROCEDURE drawLine (ed : EDITPTR; screenLine : INTEGER);
  588.   VAR fill : Rectangle;
  589.       wr   : INTEGER;
  590.       i    : INTEGER;
  591.       width: INTEGER;
  592.       extend: ARRAY [0..3] OF Point;
  593.       text : textPtr;
  594.       topLine : LONGINT;
  595.       len   : INTEGER;
  596.       clipr : Rectangle;
  597. BEGIN
  598.   IF screenLine < 0 THEN RETURN END;
  599.   WITH ed^ DO 
  600.     (* Fillrectangle berechnen *)
  601.     fill.x := BinOps.LowerInt (mtAppl.MaxWidth-1, editWork.x);
  602.     fill.y := BinOps.LowerInt (mtAppl.MaxHeight-1, editWork.y + screenLine * charHeight);
  603.     fill.w := BinOps.LowerInt (mtAppl.MaxWidth-1, editWork.x + editWork.w - 1);
  604.     fill.h := BinOps.LowerInt (mtAppl.MaxHeight-1, editWork.y + (screenLine+1) * charHeight - 1);
  605.     IF WdwManager.RectList (wdw, 0, clipr)
  606.     THEN
  607.       REPEAT
  608.         WdwManager.SetClip (hdl, clipr, TRUE);
  609.         MagicVDI.FillRectangle (hdl, fill);
  610.         v.int := MagicVDI.SetWritemode (hdl, MagicVDI.TRANSPARENT);
  611.         (* String ausgeben *)
  612.         IF StartLine + LONG (screenLine) < totalLineNr
  613.         THEN
  614.           MakeDrawLine (ed, StartLine + LONG(screenLine), theDrawLine, len);
  615.           text := ADR (theDrawLine);
  616.           (*
  617.           InqTextextend (ed, text^, extend, TRUE);
  618.           width := extend[1].x - extend[0].x;
  619.           *)
  620.           OutputLine (ed, fill.x+pixOff-leftOffset, fill.y, text^, len, width);
  621.           IF width > maxWidth THEN maxWidth := width; END;
  622.         END;
  623.         (* Jetzt noch testen, ob es im Block war *)
  624.         v.int := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  625.         IF IsInBlock (ed, StartLine+LONG(screenLine))
  626.         THEN 
  627.           MagicVDI.SetClipping (hdl, fill, TRUE);
  628.           ShowBlockMark (ed, FALSE);
  629.           ClipWork (ed);
  630.         END (* IF IsInBlock *);
  631.       UNTIL ~WdwManager.RectList (wdw, 1, clipr);
  632.     END;
  633.   END; (* WITH ed^ DO *)
  634. END drawLine;
  635.  
  636. PROCEDURE redrawLineFSM (ed : EDITPTR);
  637.   (* zeichnet currLine von currRow bis Ende neu *)
  638.   VAR 
  639.       ch :      ARRAY [0..1] OF CHAR;
  640.       extend:   ARRAY [0..3] OF Point;
  641.       width:    INTEGER;
  642.       c:        Point; (* aktuelle Zeichenposition *)
  643.       fill:     Rectangle; (* Fllrechteck *)
  644.       wr:       INTEGER;
  645.       charAdr:  POINTER TO CHAR;
  646.       strAdr:   textPtr;
  647.       saveCh:   CHAR;
  648.       lastCh:   ARRAY [0..7] OF CHAR;
  649.       i:        INTEGER;
  650.       text:     textPtr;
  651.       len:      INTEGER;
  652.       clipr:    Rectangle;
  653. BEGIN
  654.   WITH ed^ DO
  655.     (* Zeilenanfang holen *)
  656.     MakeDrawLine (ed, currLineNr, theDrawLine, len);
  657.     text := ADR(theDrawLine);
  658.     IF currRow > 0
  659.     THEN
  660.       charAdr := ADR (text^[currRow-1]);
  661.     ELSE
  662.       charAdr := ADDRESS(text);
  663.     END;
  664.     saveCh := charAdr^;
  665.     charAdr^ := 0C;
  666.     InqTextextend (ed, text^, extend, FALSE);
  667.     charAdr^ := saveCh;
  668.     c.x := editWork.x + extend[1].x - extend[0].x + pixOff - leftOffset;
  669.     c.y := editWork.y + SHORT(currLineNr - StartLine) * charHeight;
  670.  
  671.     fill.x := BinOps.LowerInt (mtAppl.MaxWidth-1, c.x);
  672.     fill.y := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y);
  673.     fill.w := BinOps.LowerInt (mtAppl.MaxWidth-1, editWork.x + editWork.w - 1);
  674.     fill.h := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y + charHeight - 1);
  675.     IF WdwManager.RectList (wdw, 0, clipr)
  676.     THEN
  677.       REPEAT
  678.         WdwManager.SetClip (hdl, clipr, TRUE);
  679.         MagicVDI.FillRectangle (hdl, fill);
  680.         (* String ausgeben *)
  681.         fill.x := BinOps.LowerInt (mtAppl.MaxWidth-1, editWork.x);
  682.         (*
  683.         InqTextextend (ed, text^, extend, FALSE);
  684.         width := extend[1].x - extend[0].x;
  685.         *)
  686.         wr := MagicVDI.SetWritemode (hdl, MagicVDI.TRANSPARENT);
  687.         OutputLine (ed, fill.x+pixOff-leftOffset, fill.y, text^, len, width);
  688.         IF width+charWidth > maxWidth THEN maxWidth := width+charWidth; END;
  689.         IF IsInBlock (ed, currLineNr)
  690.         THEN
  691.           MagicVDI.SetClipping (hdl, fill, TRUE);
  692.           ShowBlockMark (ed, FALSE);
  693.           ClipWork (ed);
  694.         END;
  695.         wr := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  696.       UNTIL ~WdwManager.RectList (wdw, 1, clipr);
  697.     END;
  698.   END; (* WITH ed^ *)
  699. END redrawLineFSM;
  700.  
  701. PROCEDURE redrawLineMono (ed : EDITPTR; insChar : BOOLEAN);
  702.   (* zeichnet currLine von currRow bis Ende neu,
  703.    * fr monospaced font
  704.    *)
  705.   VAR 
  706.       width:    INTEGER;
  707.       c:        Point; (* aktuelle Zeichenposition *)
  708.       fill:     Rectangle; (* Fllrechteck *)
  709.       wr:       INTEGER;
  710.       lastCh:   ARRAY [0..7] OF CHAR;
  711.       copy:     ARRAY [0..1] OF Rectangle;
  712.       tmp:      Rectangle;
  713.       extend:   ARRAY [0..3] OF Point;
  714.       strAdr:   textPtr;
  715.       le,
  716.       row:      INTEGER;
  717.       pscrMFDB,
  718.       pdesMFDB: MagicVDI.MFDB;
  719.       clipr:    Rectangle;
  720. BEGIN
  721.   pscrMFDB.fdAddr := NIL;
  722.   pdesMFDB.fdAddr := NIL;
  723.   WITH ed^ DO
  724.     (* Fenster nach links aus dem Bildschirm raus mit WinX? *)
  725.     IF editWork.x < 0 THEN redrawLineFSM (ed); RETURN END;
  726.     MakeDrawLine (ed, currLineNr, theDrawLine, le);
  727.     (* Zeichen unter Cursor *)
  728.     lastCh[0] := theDrawLine[currRow];
  729.     lastCh[1] := theDrawLine[currRow+1];
  730.     lastCh[2] := 0C;
  731.     (* zeichenposition berechnen *)
  732.     c.x := editWork.x + pixOff - leftOffset + currRow * charWidth;
  733.     c.y := editWork.y + SHORT (currLineNr-StartLine) * charHeight ;
  734.  
  735.     fill.x := BinOps.LowerInt (mtAppl.MaxWidth-1, c.x);
  736.     fill.y := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y);
  737.     fill.w := BinOps.LowerInt (mtAppl.MaxWidth-1, c.x+ charWidth - 1);
  738.     fill.h := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y + charHeight-1);
  739.     IF WdwManager.RectList (wdw, 0, clipr)
  740.     THEN
  741.       REPEAT
  742.         WdwManager.SetClip (hdl, clipr, TRUE);
  743.     
  744.         IF insertMode OR ~insChar OR (ORD(theDrawLine[currRow]) < 32)
  745.         THEN
  746.           (* Bitblocktransfer der brigen Zeichen nach hinten *)
  747.           WITH copy[0] DO
  748.             x := BinOps.LowerInt (mtAppl.MaxWidth-1, c.x);
  749.             y := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y);
  750.             w := BinOps.LowerInt (mtAppl.MaxWidth-1, editWork.x+editWork.w - charWidth-1);
  751.             h := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y + charHeight-1);
  752.           END;
  753.           WITH copy[1] DO
  754.             x := BinOps.LowerInt (mtAppl.MaxWidth-1, c.x+charWidth);
  755.             y := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y);
  756.             w := BinOps.LowerInt (mtAppl.MaxWidth-1, editWork.x+editWork.w - 1);
  757.             h := BinOps.LowerInt (mtAppl.MaxHeight-1, c.y + charHeight-1);
  758.           END;
  759.           (* Beim L”schen BitBlk-Transfer um 1 Zeichen zurck *)
  760.           IF ~insChar THEN tmp:= copy[0]; copy[0]:=copy[1];copy[1]:= tmp; END;
  761.           MagicVDI.CopyRasterOpaque(hdl, 3, copy, pscrMFDB, pdesMFDB);
  762.           (* Noch Zeilenbreite bestimmen *)
  763.           width := le * charWidth;
  764.           IF width+charWidth > maxWidth THEN maxWidth := width+charWidth; END;
  765.         END;
  766.         IF ~insChar 
  767.         THEN
  768.           (* Zeilenende noch l”schen und ggf neuzeichnen *)
  769.           copy[0].x := copy[0].w-charWidth;
  770.           MagicVDI.FillRectangle (hdl, copy[0]);
  771.           row := ((copy[0].x -editWork.x + leftOffset -pixOff) DIV charWidth);
  772.           IF (row < le) & (row >= 0)
  773.           THEN
  774.             strAdr := ADR(theDrawLine[row]);
  775.             wr := MagicVDI.SetWritemode (hdl, MagicVDI.TRANSPARENT);
  776.             copy[0].x := (editWork.x - leftOffset + pixOff) + row * charWidth;
  777.             Text (ed, copy[0].x, copy[0].y, strAdr^);
  778.           END;
  779.         ELSE
  780.           MagicVDI.FillRectangle (hdl, fill);
  781.           (* Zeichen ausgeben *)
  782.           wr := MagicVDI.SetWritemode (hdl, MagicVDI.TRANSPARENT);
  783.           Text (ed, fill.x, fill.y, lastCh);
  784.         END;
  785.         (* Blockmarkierung erneuern *)
  786.         IF IsInBlock (ed, currLineNr)
  787.         THEN
  788.           MagicVDI.SetClipping (hdl, fill, TRUE);
  789.           ShowBlockMark (ed, FALSE);
  790.           ClipWork (ed);
  791.         END;
  792.         wr := MagicVDI.SetWritemode (hdl, MagicVDI.REPLACE);
  793.       UNTIL ~WdwManager.RectList (wdw, 1, clipr);
  794.     END;
  795.   END; (* WITH ed^ *)
  796. END redrawLineMono;
  797.  
  798. PROCEDURE redrawLine (ed : EDITPTR; insChar : BOOLEAN; full : BOOLEAN);
  799. BEGIN
  800.   IF ed^.wdw # WdwManager.theTopWindow
  801.   THEN
  802.     redrawLineFSM (ed);
  803.   ELSIF ed^.monoSpaced & ~full & ~ed^.realTabs & ~ed^.isFSM (* added "& ~isFSM" for Monospaced 821 Font *)
  804.   THEN
  805.     redrawLineMono (ed, insChar)
  806.   ELSIF (ed^.realTabs OR full) & ~ed^.isFSM
  807.   THEN
  808.     drawLine (ed, SHORT(ed^.currLineNr-ed^.StartLine));
  809.   ELSE
  810.     redrawLineFSM (ed);
  811.   END;
  812. END redrawLine;
  813.  
  814.         (* Bl„tterfunktionen *)
  815.  
  816. PROCEDURE CenterCurrline (ed : EDITPTR);
  817.   VAR oldLine : LONGINT;
  818.       maxOffset : INTEGER;
  819.       oldOffset: INTEGER;
  820.       x, y    : INTEGER;
  821.       centered: BOOLEAN;
  822. BEGIN
  823.   WITH ed^ DO 
  824.     centered := FALSE;
  825.     IF (currLineNr < StartLine) OR (currLineNr > StartLine + LONG(windLines)-1)
  826.     THEN
  827.       HideMouse();
  828.       HideCursor (ed);
  829.       (* Zentrieren ist n”tig! *)
  830.       oldLine := StartLine;
  831.       SetStartLine (ed, BinOps.HigherLInt(0, currLineNr - (LONG(windLines) DIV 2)), TRUE);
  832.       centered := TRUE;
  833.       ShowCursor (ed);
  834.       ShowMouse(FALSE);
  835.     END;
  836.     getCharPos (ed, currLineNr, currRow, x, y);
  837.     IF (x < editWork.x) OR (x >= editWork.x + editWork.w) OR ((editWork.w > maxWidth) & (leftOffset > 0))
  838.     THEN
  839.       HideMouse();
  840.       HideCursor (ed);
  841.       (* Zentrieren ist n”tig! *)
  842.       oldOffset := leftOffset;
  843.       maxOffset := BinOps.HigherInt (0, maxWidth - editWork.w);
  844.       (* neuen offset berechnen *)
  845.       leftOffset := BinOps.HigherInt (0, oldOffset+(x-editWork.x) - charWidth*5);
  846.       leftOffset := BinOps.LowerInt (leftOffset, maxOffset);
  847.       IF x + oldOffset < editWork.w - charWidth*2 THEN leftOffset := 0; END;
  848.       SetDocument (ed);
  849.       centered := TRUE;
  850.       ShowCursor (ed);
  851.       ShowMouse(FALSE);
  852.     END;
  853.     IF centered
  854.     THEN
  855.       SetInfoLine (ed);
  856.     END;
  857.   END;
  858. END CenterCurrline;
  859.  
  860. BEGIN
  861.   control7:= ADR (VDIControl[7]);
  862.   control9:= ADR (VDIControl[9]);
  863. END EditDraw.
  864.